package com.lifeverse.entity;

import com.lifeverse.entity.enums.CollaborationTaskStatus;
import com.lifeverse.entity.enums.CollaborationTaskType;
import jakarta.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 协作任务实体类
 * 表示生命体间的协作任务
 */
@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "collaboration_tasks", indexes = {
    @Index(name = "idx_collaboration_task_title", columnList = "title"),
    @Index(name = "idx_collaboration_task_type", columnList = "type"),
    @Index(name = "idx_collaboration_task_status", columnList = "status"),
    @Index(name = "idx_collaboration_task_initiator", columnList = "initiator_id"),
    @Index(name = "idx_collaboration_task_start_time", columnList = "start_time"),
    @Index(name = "idx_collaboration_task_deadline", columnList = "deadline")
})
public class CollaborationTask extends BaseEntity {
    
    /**
     * 任务标题
     */
    @Column(name = "title", nullable = false, length = 200)
    private String title;
    
    /**
     * 任务描述
     */
    @Column(name = "description", columnDefinition = "TEXT")
    private String description;
    
    /**
     * 任务类型
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "type", nullable = false, length = 30)
    private CollaborationTaskType type;
    
    /**
     * 任务状态
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "status", nullable = false, length = 30)
    private CollaborationTaskStatus status = CollaborationTaskStatus.PENDING;
    
    /**
     * 任务发起者
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "initiator_id", nullable = false)
    private LifeEntity initiator;
    
    /**
     * 任务协调者
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "coordinator_id")
    private LifeEntity coordinator;
    
    /**
     * 关联决策
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "decision_id")
    private Decision decision;
    
    /**
     * 任务优先级（1-10）
     */
    @Column(name = "priority", nullable = false)
    private Integer priority = 5;
    
    /**
     * 预期开始时间
     */
    @Column(name = "expected_start_time")
    private LocalDateTime expectedStartTime;
    
    /**
     * 实际开始时间
     */
    @Column(name = "start_time")
    private LocalDateTime startTime;
    
    /**
     * 预期结束时间
     */
    @Column(name = "expected_end_time")
    private LocalDateTime expectedEndTime;
    
    /**
     * 实际结束时间
     */
    @Column(name = "end_time")
    private LocalDateTime endTime;
    
    /**
     * 任务截止时间
     */
    @Column(name = "deadline")
    private LocalDateTime deadline;
    
    /**
     * 所需参与者数量
     */
    @Column(name = "required_participants", nullable = false)
    private Integer requiredParticipants = 1;
    
    /**
     * 当前参与者数量
     */
    @Column(name = "current_participants", nullable = false)
    private Integer currentParticipants = 0;
    
    /**
     * 最大参与者数量
     */
    @Column(name = "max_participants")
    private Integer maxParticipants;
    
    /**
     * 任务目标
     */
    @Column(name = "objectives", columnDefinition = "TEXT")
    private String objectives;
    
    /**
     * 成功标准
     */
    @Column(name = "success_criteria", columnDefinition = "TEXT")
    private String successCriteria;
    
    /**
     * 所需技能（JSON格式）
     */
    @Column(name = "required_skills", columnDefinition = "TEXT")
    private String requiredSkills;
    
    /**
     * 所需资源（JSON格式）
     */
    @Column(name = "required_resources", columnDefinition = "TEXT")
    private String requiredResources;
    
    /**
     * 任务进度（0-100）
     */
    @Column(name = "progress", nullable = false, precision = 5, scale = 2)
    private BigDecimal progress = BigDecimal.ZERO;
    
    /**
     * 协作效果评分（0-100）
     */
    @Column(name = "collaboration_score", precision = 5, scale = 2)
    private BigDecimal collaborationScore;
    
    /**
     * 任务复杂度（1-10）
     */
    @Column(name = "complexity_level", nullable = false)
    private Integer complexityLevel = 5;
    
    /**
     * 预期收益
     */
    @Column(name = "expected_benefit", precision = 10, scale = 2)
    private BigDecimal expectedBenefit;
    
    /**
     * 实际收益
     */
    @Column(name = "actual_benefit", precision = 10, scale = 2)
    private BigDecimal actualBenefit;
    
    /**
     * 任务标签（JSON格式）
     */
    @Column(name = "tags", length = 500)
    private String tags;
    
    /**
     * 任务配置（JSON格式）
     */
    @Column(name = "configuration", columnDefinition = "TEXT")
    private String configuration;
    
    /**
     * 任务元数据（JSON格式）
     */
    @Column(name = "metadata", columnDefinition = "TEXT")
    private String metadata;
    
    /**
     * 协作历史记录（JSON格式）
     */
    @Column(name = "collaboration_history", columnDefinition = "TEXT")
    private String collaborationHistory;
    
    /**
     * 学习成果（JSON格式）
     */
    @Column(name = "learning_outcomes", columnDefinition = "TEXT")
    private String learningOutcomes;
    
    /**
     * 任务参与者
     */
    @OneToMany(mappedBy = "collaborationTask", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<CollaborationParticipant> participants = new ArrayList<>();
    
    /**
     * 协作冲突记录
     */
    @OneToMany(mappedBy = "collaborationTask", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<CollaborationConflict> conflicts = new ArrayList<>();
    
    /**
     * 开始任务
     */
    public void start() {
        if (this.status.canStartCollaboration()) {
            this.status = CollaborationTaskStatus.IN_PROGRESS;
            this.startTime = LocalDateTime.now();
        }
    }
    
    /**
     * 完成任务
     */
    public void complete(BigDecimal actualBenefit) {
        this.status = CollaborationTaskStatus.COMPLETED;
        this.endTime = LocalDateTime.now();
        this.progress = BigDecimal.valueOf(100);
        this.actualBenefit = actualBenefit;
    }
    
    /**
     * 取消任务
     */
    public void cancel(String reason) {
        this.status = CollaborationTaskStatus.CANCELLED;
        this.endTime = LocalDateTime.now();
        this.setRemark((this.getRemark() != null ? this.getRemark() + " | " : "") + "取消原因: " + reason);
    }
    
    /**
     * 暂停任务
     */
    public void pause(String reason) {
        if (this.status.canPause()) {
            this.status = CollaborationTaskStatus.PAUSED;
            this.setRemark((this.getRemark() != null ? this.getRemark() + " | " : "") + "暂停原因: " + reason);
        }
    }
    
    /**
     * 恢复任务
     */
    public void resume() {
        if (this.status.canResume()) {
            this.status = CollaborationTaskStatus.IN_PROGRESS;
        }
    }
    
    /**
     * 标记任务失败
     */
    public void markFailed(String reason) {
        this.status = CollaborationTaskStatus.FAILED;
        this.endTime = LocalDateTime.now();
        this.setRemark((this.getRemark() != null ? this.getRemark() + " | " : "") + "失败原因: " + reason);
    }
    
    /**
     * 更新进度
     */
    public void updateProgress(BigDecimal newProgress) {
        if (newProgress != null && newProgress.compareTo(BigDecimal.ZERO) >= 0 && 
            newProgress.compareTo(BigDecimal.valueOf(100)) <= 0) {
            this.progress = newProgress;
            
            // 如果进度达到100%，自动完成任务
            if (newProgress.compareTo(BigDecimal.valueOf(100)) == 0 && !this.status.isCompleted()) {
                this.complete(this.expectedBenefit);
            }
        }
    }
    
    /**
     * 增加参与者
     */
    public void addParticipant() {
        this.currentParticipants++;
        
        // 如果达到所需参与者数量，更新状态
        if (this.currentParticipants >= this.requiredParticipants && 
            this.status == CollaborationTaskStatus.WAITING_FOR_COLLABORATION) {
            this.status = CollaborationTaskStatus.COLLABORATING;
        }
    }
    
    /**
     * 移除参与者
     */
    public void removeParticipant() {
        if (this.currentParticipants > 0) {
            this.currentParticipants--;
            
            // 如果参与者不足，更新状态
            if (this.currentParticipants < this.requiredParticipants && 
                this.status == CollaborationTaskStatus.COLLABORATING) {
                this.status = CollaborationTaskStatus.WAITING_FOR_COLLABORATION;
            }
        }
    }
    
    /**
     * 判断是否超时
     */
    public boolean isOverdue() {
        return deadline != null && LocalDateTime.now().isAfter(deadline) && !status.isCompleted();
    }
    
    /**
     * 判断是否可以加入更多参与者
     */
    public boolean canAddMoreParticipants() {
        return maxParticipants == null || currentParticipants < maxParticipants;
    }
    
    /**
     * 计算任务持续时间（分钟）
     */
    public long getDurationMinutes() {
        if (startTime == null) {
            return 0;
        }
        
        LocalDateTime endTimeToUse = endTime != null ? endTime : LocalDateTime.now();
        return java.time.Duration.between(startTime, endTimeToUse).toMinutes();
    }
    
    /**
     * 计算预期持续时间（分钟）
     */
    public long getExpectedDurationMinutes() {
        if (expectedStartTime == null || expectedEndTime == null) {
            return 0;
        }
        
        return java.time.Duration.between(expectedStartTime, expectedEndTime).toMinutes();
    }
    
    /**
     * 计算收益率
     */
    public BigDecimal calculateBenefitRate() {
        if (expectedBenefit == null || expectedBenefit.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        
        if (actualBenefit == null) {
            return BigDecimal.ZERO;
        }
        
        return actualBenefit.divide(expectedBenefit, 4, java.math.RoundingMode.HALF_UP);
    }
    
    /**
     * 判断是否需要更多参与者
     */
    public boolean needsMoreParticipants() {
        return currentParticipants < requiredParticipants;
    }
    
    /**
     * 判断参与者是否过多
     */
    public boolean hasTooManyParticipants() {
        return maxParticipants != null && currentParticipants > maxParticipants;
    }
}